# write by hashaki
# first edit on 2018/11/13
# last change on 2018/12/18
# gate exchange API

import http.client
import urllib
import json
import hashlib
import hmac


class GateIO:
    def __init__(self):
        self.exchange_msg={'name':'gateio'}
        self.__url_qry = 'data.gateio.co'
        self.__url_trade='api.gateio.co'
        self.__apiKey = None
        self.__secretKey = None

    '''
        # 该API支持什么操作
        has={
                'CORS': False,
                'createMarketOrder': False,
                'Tickers': True,
                'withdraw': True,
                'createDepositAddress': True,
                'DepositAddress': True,
                'ClosedOrders': True,
                'OpenOrders': True,
                'OrderTrades': True,
                'Orders': True,
                'Order': True}
            
        api={'pubilc':{
            'get':['pairs',
                        'marketinfo',
                        'marketlist',
                        'tickers',
                        'ticker/{id}',
                        'orderBook/{id}',
                        'trade/{id}',
                        'tradeHistory/{id}',
                        'tradeHistory/{id}/{tid}'
                        ]
                        },
                'private':{'post':
                    ['balances',
                        'depositAddress',
                        'newAddress',
                        'depositsWithdrawals',
                        'buy',
                        'sell',
                        'cancelOrder',
                        'cancelAllOrders',
                        'getOrder',
                        'openOrders',
                        'tradeHistory',
                        'withdraw']
                        }
                }
    '''
    
    #----------------------------------交易所通信基础函数------------------------------------
    @staticmethod
    def getSign(params, secretKey):
        bSecretKey = bytes(secretKey, encoding='utf8')

        sign = ''
        for key in params.keys():
            value = str(params[key])
            sign += key + '=' + value + '&'
        bSign = bytes(sign[:-1], encoding='utf8')

        mySign = hmac.new(bSecretKey, bSign, hashlib.sha512).hexdigest()
        return mySign

    @staticmethod
    def httpGet(url, resource, params=''):
        conn = http.client.HTTPSConnection(url, timeout=10)
        conn.request("GET", resource + '/' + params)
        response = conn.getresponse()
        data = response.read().decode('utf-8')
        return json.loads(data)
    
    @staticmethod
    def httpPost(url, resource, params, apiKey, secretKey):
        headers = {
            "Content-type" : "application/x-www-form-urlencoded",
            "KEY":apiKey,
            "SIGN":GateIO.getSign(params, secretKey)
     }

        conn = http.client.HTTPSConnection(url, timeout=10)

        tempParams = urllib.parse.urlencode(params) if params else ''

        conn.request("POST", resource, tempParams, headers)
        response = conn.getresponse()
        data = response.read().decode('utf-8')
        params.clear()
        conn.close()
        return data
    #------------------------------设置key--------------------------------------------
    def setKey(self,apiKey,secrete_key):
        self.__apiKey=apiKey
        self.__secretKey=secrete_key

    # -----------------------------功能函数--------------------------------------------
    #所有交易对
    def pairs(self):
        '''pairs()[2]'''
        URL = "/api2/1/pairs"
        params=''
        return GateIO.httpGet(self.__url_qry, URL, params)

    #市场订单参数
    def marketinfo(self):
        '''市场信息，小数点后面位数，最小数额，手续费 大字典'pairs',返回'result':'true'
                marketinfo()['result']'''
        URL = "/api2/1/marketinfo"
        params=''
        return GateIO.httpGet(self.__url_qry, URL, params)

    #交易市场详细行情
    def marketlist(self):
        '''在交易所中排名下来的详细市场信息，比如总量，买卖量，排第几位，涨跌幅度，现价，锚定什么法币
                marketlist()['data'][0]'''
        URL = "/api2/1/marketlist"
        params=''
        return GateIO.httpGet(self.__url_qry, URL, params)

    #所有交易行情
    def tickers(self):
        '''交易数据，24小时最高价，最近价，24小时最低价，涨跌幅，还有一些baseVolume和quoteVolume不知道是什么
                tickers()['eos_usdt']'''
        URL = "/api2/1/tickers"
        params=''
        return GateIO.httpGet(self.__url_qry, URL, params)

    # 所有交易对市场深度
    def orderBooks(self):
        ''' 深度,bids卖单，asks买单,返回的是深度还有挂单量
                orderBooks()['eos_usdt']['bids']'''
        URL = "/api2/1/orderBooks"
        param=''
        return GateIO.httpGet(self.__url_qry, URL, param)

    #单项交易行情
    def ticker(self, param):
        '''Ticker就是指定币种的Tickers
                ticker('btc_usdt')'''
        URL = "/api2/1/ticker"
        return GateIO.httpGet(self.__url_qry, URL, param)

    # 单项交易对市场深度
    def orderBook(self, param):
        '''orderBook('btc_usdt')'''
        URL = "/api2/1/orderBook"
        return GateIO.httpGet(self.__url_qry, URL, param)

    # 历史成交记录
    def tradeHistory(self, param):
        '''tradeHistory('eos_usdt')'''
        URL = "/api2/1/tradeHistory"
        return GateIO.httpGet(self.__url_trade, URL, param)

    # K线
    def kLine(self,param,sec=None,hour=None):
        '''[时间，交易量，收盘价，最高价，最低价，开盘价
            kLine('btc_usdt')'''
        import requests
        URL='/api2/1/candlestick2/'
        if sec is None or hour is None:
            return requests.get('http://'+self.__url_qry+URL+param).json()
        elif sec is not None and hour is not None:
            return requests.get('http://'+self.__url_qry+URL+param+'?group_sec='+str(sec)+'&range_hour='+str(hour)).json()

    ## Methods that make use of the users keys
    #获取帐号资金余额
    def balances(self):
        '''balances()
        返回数据类型{"result":"true","available":{"ETH":"0.000008","EON":"5.7260438","LEDU":"0.00009643","IQ":"29.20282338","USDT":"0.67739399"
        ,"EOS":"154.0532764","LRC":"0.00868576","AE":"0.0095654","GXS":"0.00083","MEETONE":"2.8630219","BTM":"0.00440496","ADD":"2.8630219","LRN":"0.00017371",
        "BTS":"0.000006","EOP":"5.7260438"},"locked":{"ETH":"0","EON":"0","LEDU":"0","IQ":"0","USDT":"0","EOS":"0","LRC":"0","AE":"0","GXS":"0","MEETONE":"0","BTM":"0",
        "ADD":"0","LRN":"0","BTS":"0","EOP":"0"}}'''
        URL = "/api2/1/private/balances"
        param = {}
        return GateIO.httpPost(self.__url_trade, URL, param, self.__apiKey, self.__secretKey)

    # 获取充值地址
    def depositAddres(self,param):
        '''depositAddres('btc')'''
        URL = "/api2/1/private/depositAddress"
        params = {'currency':param}
        return GateIO.httpPost(self.__url_trade, URL, params, self.__apiKey, self.__secretKey)

    # 获取充值提现历史
    def depositsWithdrawals(self, start,end):
        '''depositsWithdrawals('1469092370', '1569092370') '''
        URL = "/api2/1/private/depositsWithdrawals"
        params = {'start': start,'end':end}
        return GateIO.httpPost(self.__url_trade, URL, params, self.__apiKey, self.__secretKey)

    # 买入
    def buy(self, currencyPair,rate, amount):
        ''' buy('etc_btc', '0.001', '123')'''
        URL = "/api2/1/private/buy"
        params = {'currencyPair': currencyPair,'rate':rate, 'amount':amount}
        return GateIO.httpPost(self.__url_trade, URL, params, self.__apiKey, self.__secretKey)

    # 卖出
    def sell(self, currencyPair, rate, amount):
        ''' sell('etc_btc', '0.001', '123')'''
        URL = "/api2/1/private/sell"
        params = {'currencyPair': currencyPair, 'rate': rate, 'amount': amount}
        return GateIO.httpPost(self.__url_trade, URL, params, self.__apiKey, self.__secretKey)

    # 取消订单
    def cancelOrder(self, orderNumber, currencyPair):
        '''cancelOrder('267040896', 'etc_btc') '''
        URL = "/api2/1/private/cancelOrder"
        params = {'orderNumber': orderNumber, 'currencyPair': currencyPair}
        return GateIO.httpPost(self.__url_trade, URL, params, self.__apiKey, self.__secretKey)

    # 取消所有订单
    def cancelAllOrders(self, type, currencyPair):
        ''' cancelAllOrders('0', 'etc_btc')'''
        URL = "/api2/1/private/cancelAllOrders"
        params = {'type': type, 'currencyPair': currencyPair}
        return GateIO.httpPost(self.__url_trade, URL, params, self.__apiKey, self.__secretKey)

    # 获取下单状态
    def getOrder(self, orderNumber, currencyPair):
        '''getOrder('267040896', 'eth_btc') '''
        URL = "/api2/1/private/getOrder"
        params = {'orderNumber': orderNumber, 'currencyPair': currencyPair}
        return GateIO.httpPost(self.__url_trade, URL, params, self.__apiKey, self.__secretKey)

    # 获取我的当前挂单列表
    def openOrders(self):
        ''' openOrders()'''
        URL = "/api2/1/private/openOrders"
        params = {}
        return GateIO.httpPost(self.__url_qry, URL, params, self.__apiKey, self.__secretKey)

    # 获取我的24小时内成交记录
    def mytradeHistory(self, currencyPair, orderNumber):
        '''mytradeHistory('etc_btc', '267040896')'''
        URL = "/api2/1/private/tradeHistory"
        params = {'currencyPair': currencyPair, 'orderNumber': orderNumber}
        return GateIO.httpPost(self.__url_trade, URL, params, self.__apiKey, self.__secretKey)

    # 提现
    def withdraw(self, currency, amount, address):
        '''withdraw('btc', '88', btcAddress) '''
        URL = "/api2/1/private/withdraw"
        params = {'currency': currency, 'amount': amount,'address':address}
        return GateIO.httpPost(self.__url_trade, URL, params, self.__apiKey, self.__secretKey)
